﻿using Microsoft.VisualStudio.Modeling;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace Project.Co_DataTransformationPrototype.UI
{
    public partial class SplitOperationForm : Form
    {
        public Store store;
        public Entity sourceEntity;
        public Entity targetEntity;

        public SplitOperationForm(Entity sourceEntity)
        {
            this.store = sourceEntity.Store;
            this.sourceEntity = sourceEntity;
            InitializeComponent();
        }

        private void SplitOperationForm_Load(object sender, EventArgs e)
        {
            txtSourceEntity.Text = sourceEntity.Name;
            lstbAttributes.Items.AddRange(sourceEntity.EntityAttributes.OrderBy(a => a.CurrentName).ToArray());
        }

        private void lstbAttributes_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lstbAttributes.SelectedItems.Count > 0)
                btnExecute.Enabled = true;
            else
                btnExecute.Enabled = false;
        }

        private void rdbSelectEntity_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbSelectEntity.Checked)
            {
                cboEntities.Items.AddRange(store.ElementDirectory.FindElements<Entity>().OrderBy(ent => ent.CurrentName).ToArray());
                lblCboEntities.Visible = true;
                cboEntities.Visible = true;
                cboEntities.Focus();

                txtTargetEntity.Text = string.Empty;
                lblTxtTargetEntity.Visible = false;
                txtTargetEntity.Visible = false;
            }
        }

        private void rdbCreateEntity_CheckedChanged(object sender, EventArgs e)
        {
            if (rdbCreateEntity.Checked)
            {
                targetEntity = null;
                cboEntities.Items.Clear();
                lblTxtTargetEntity.Visible = true;
                txtTargetEntity.Visible = true;
                txtTargetEntity.Text = string.Empty;

                lblCboEntities.Visible = false;
                cboEntities.Visible = false;
            }
        }

        private void txtTargetEntity_Validating(object sender, CancelEventArgs e)
        {
            if (rdbCreateEntity.Checked && string.IsNullOrEmpty(txtTargetEntity.Text))
            {
                string errorMsg = "Please specify a name for the new entity";
                            
                // Cancel the event and reset form and clear textbox.
                e.Cancel = true;
                rdbCreateEntity.Checked = true;

                // Set the ErrorProvider error with the text to display.
                this.errPrvTargetEntityDefinition.SetError(txtTargetEntity, errorMsg);
            }
        }

        private void cboEntities_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cboEntities.SelectedItem != null)
                targetEntity = (cboEntities.SelectedItem as Entity);
            else
                targetEntity = null;
        }

        private void cboEntities_Validating(object sender, CancelEventArgs e)
        {
            if (rdbSelectEntity.Checked && targetEntity == null)
            {
                string errorMsg = "Please select a target entity";

                // Cancel the event and reset form and clear textbox.
                e.Cancel = true;
                rdbCreateEntity.Checked = true;

                // Set the ErrorProvider error with the text to display.
                this.errPrvTargetEntityDefinition.SetError(cboEntities, errorMsg);
            }
        }

        private void btnExecute_Click(object sender, EventArgs e)
        {
            System.Guid newEntityID = System.Guid.Empty;
            Operators.Operator op = new Operators.Operator(store);
            this.errPrvTargetEntityDefinition.Clear();

            // Determine the target entity to which to send the selected attributes
            if (rdbCreateEntity.Checked)
            {
                op = op.CreateOperator(new List<EntityInfo> { new EntityInfo(sourceEntity.ModelRoot, txtTargetEntity.Text, false, null) }, out newEntityID);
                targetEntity = store.ElementDirectory.FindElement(newEntityID) as Entity;
            }

            // Move selected attributes to the target entity
            if (targetEntity != null)
            {
                // Transaction is required if you want to update elements.
                using (Transaction t = store.TransactionManager.BeginTransaction("Splitting entity's attributes"))
                {
                    Entity source = null;
                    foreach (EntityAttribute attribute in lstbAttributes.SelectedItems.OfType<EntityAttribute>().ToList())
                    {
                        source = attribute.Entity as Entity;
                        targetEntity.EntityAttributes.Add(attribute.Copy() as EntityAttribute);
                        source.EntityAttributes.Remove(attribute);
                    }
                    t.Context.Add(Operators.GetSplitOpTransactionKey, source);
                    t.Commit();
                }
                this.DialogResult = System.Windows.Forms.DialogResult.OK;
            }
            this.Hide();
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Hide();
        }

    }
}
